package org.zoomdev.zoom.asm;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.GeneratorAdapter;
import org.objectweb.asm.commons.Method;

import java.util.ArrayList;
import java.util.List;

public class MethodBuilder {
    private final String name;
    private Type returnType = Type.VOID_TYPE;
    private Type[] paramTypes = new Type[0];
    private int access = Opcodes.ACC_PUBLIC;
    private final List<Instruction> instructions = new ArrayList<>();

    public MethodBuilder(String name) {
        this.name = name;
    }

    public MethodBuilder withAccess(int access) {
        this.access = access;
        return this;
    }

    public MethodBuilder returns(Class<?> returnType) {
        this.returnType = Type.getType(returnType);
        return this;
    }

    public MethodBuilder params(Class<?>... paramTypes) {
        this.paramTypes = new Type[paramTypes.length];
        for (int i = 0; i < paramTypes.length; i++) {
            this.paramTypes[i] = Type.getType(paramTypes[i]);
        }
        return this;
    }

    public MethodBuilder addInstruction(Instruction instruction) {
        instructions.add(instruction);
        return this;
    }

    public void build(ClassWriter cw, String className) {
        Method method = new Method(name, returnType, paramTypes);
        GeneratorAdapter mg = new GeneratorAdapter(access, method, null, null, cw);
        mg.visitCode();

        // 应用所有指令
        for (Instruction instruction : instructions) {
            instruction.apply(mg);
        }

        mg.endMethod();
    }
}
